class EnumConst {
    constructor({ value, label, name, subEnumValues }) {
        this.value = value;
        this.label = label;
        this.name = name;
        if (subEnumValues) this.subEnumValues = subEnumValues;
    }
}

export class EnumDef {
    _enums = []
    constructor(members = []) {
        members.forEach((item, i) => {
            const { name, value } = item;
            if (name) this[name] = value;
            this._enums[i] = new EnumConst(item);
        });
    }

    getMember(value) {
        return this._enums.find(item => item.value === value);
    }

    getAllMembers() {
        return this._enums.map(item => ({ ...item }));
    }

    getLabel(value, fallback = '-') {
        const enumConst = this.getMember(value);
        return enumConst ? enumConst.label : fallback;
    }

    getSubEnumValues(value) {
        const enumConst = this.getMember(value);
        return (enumConst && enumConst.subEnumValues) || [];
    }

    toJSON() {
        return {
            members: this._enums.map(({ value, name, label }) =>
                ({ value, name, label }))
        };
    }

    static fromJSON(json) {
        const data = typeof json === 'string' ? JSON.parse(json) : json;

        if (!data.members) {
            data.members = data._enums;
        }
        if (!Array.isArray(data.members)) {
            data.members = [data._enums]; // 尝试包装成数组
        }
        return new EnumDef(data.members);
    }
}